www.gusucode.com > wxApp PHP版微信小程序CMS系统 v1.0PHP源码程序 > wxApp PHP版微信小程序CMS系统 v1.0/wxAppCMS_v1.0.0/wxAppCMS_v1.0.0/iPHP/core/iFS.class.php
<?php /** * iPHP - i PHP Framework * Copyright (c) iiiPHP.com. All rights reserved. * * @author iPHPDev <master@iiiphp.com> * @website http://www.iiiphp.com * @license http://www.iiiphp.com/license * @version 2.1.0 */ class iFS { public static $force_ext = false; public static $valid_ext = true; public static $config = null; public static $data = null; public static $CALLABLE = null; public static $ERROR = null; public static $ERROR_TYPE = false; public static $EXTS = array( "png", "jpg", "jpeg", "gif", "bmp", "webp", "psd", "tif", "flv", "swf", "mkv", "avi", "rm", "rmvb", "mpeg", "mpg", "mp4", "ogg", "ogv", "mov", "wmv", "webm", "mp3","aac","m4a", "wav", "mid", "amr", "rar", "zip", "tar", "gz", "7z", "bz2", "cab", "iso", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "txt", "md", "xml", "apk", "ipa", "html", "htm", "shtml", ); public static function init($config) { self::$config = $config; } public static function config($config) { self::$config = array_merge(self::$config, $config); } public static function url($urls=null) { $urls===null && $urls = self::$config['url']; return trim($urls); } public static function ex($f) { return @stat($f) === false ? false : true; } public static function is_url($url) { return self::checkHttp($url); } public static function is_file($file) { return @is_file($file); } public static function is_dir($path) { return @is_dir($path); } public static function is_readable($file) { return @is_readable($file); } public static function is_writable($file) { return @is_writable($file); } public static function atime($file) { return @fileatime($file); } public static function mtime($file) { return @filemtime($file); } public static function check($fn) { strpos($fn, '..') !== false && trigger_error('What are you doing?',E_USER_ERROR); } public static function checkHttp($url) { if (stripos($url, 'http://') === false && stripos($url, 'https://') === false) { return false; } else { return true; } } public static function del($fn, $check = 1) { return self::rm($fn, $check); } public static function rm($fn, $check = 1) { $check && self::check($fn); @chmod($fn, 0777); $del = @unlink($fn); self::hook('delete',array($fn)); return $del; } public static function read($fn, $check = 1, $method = "rb") { $check && self::check($fn); if (function_exists('file_get_contents') && $method != "rb") { $filedata = file_get_contents($fn); } else { if ($handle = fopen($fn, $method)) { flock($handle, LOCK_SH); $filedata = @fread($handle, (int) filesize($fn)); fclose($handle); } } return $filedata; } public static function write($fn, $data, $check = 1, $method = "wb+", $iflock = 1, $chmod = 0) { $check && self::check($fn); @touch($fn); $handle = fopen($fn, $method); $iflock && flock($handle, LOCK_EX); fwrite($handle, $data); $method == "rb+" && ftruncate($handle, strlen($data)); fclose($handle); $chmod && @chmod($fn, 0644); self::hook('write',array($fn,$data)); } public static function backup($path, $target) { if (self::ex($path)) { self::mkdir(dirname($target)); return @rename($path, $target); } return false; } public static function escape_dir($dir) { $dir = str_replace(array("'", '#', '=', '`', '$', '%', '&', ';',"\0"), '', $dir); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } //创建目录 public static function mkdir($d) { $d = self::escape_dir($d); $d = str_replace('//', '/', $d); if (file_exists($d)) { return @is_dir($d); } // Attempting to create the directory may clutter up our display. if (@mkdir($d)) { $stat = @stat(dirname($d)); $dir_perms = $stat['mode'] & 0007777; // Get the permission bits. @chmod($d, $dir_perms); return true; } elseif (is_dir(dirname($d))) { return false; } // If the above failed, attempt to create the parent node, then try again. if (($d != '/') && (self::mkdir(dirname($d)))) { return self::mkdir($d); } return false; } public static function checkdir($dirpath) { if (empty($dirpath)) { return false; } $dirpath = rtrim($dirpath, '/') . '/'; if ($fp = @fopen($dirpath . 'iFS.test.txt', "wb")) { @fclose($fp); @unlink($dirpath . 'iFS.test.txt'); return true; } else { return false; } } //删除目录 public static function rmdir($dir, $df = true, $ex = NULL) { $exclude = array('.', '..'); $ex && $exclude = array_merge($exclude, (array) $ex); if ($dh = @opendir($dir)) { while (($file = readdir($dh)) !== false) { if (!in_array($file, $exclude)) { $path = $dir . '/' . $file; is_dir($path) ? self::rmdir($path, $df) : ($df ? @unlink($path) : null); } } closedir($dh); } return @rmdir($dir); } //获取文件夹下所有文件/文件夹列表 public static function fileList($dir,$pattern='*'){ $lists = array(); $dir = trim($dir, '/'); foreach(glob($dir.'/'.$pattern) as $value){ $lists[] = $value; if(is_dir($value)){ $_lists = self::fileList($value,$pattern); $lists = array_merge($lists,$_lists); } } return (array)$lists; } //获取文件夹列表 public static function folder($dir = '', $type = NULL) { $dir = trim($dir, '/'); $_GET['dir'] && $gDir = trim($_GET['dir'], '/'); // print_r('$dir='.$dir.'<br />'); // print_r('$gDir='.$gDir.'<br />'); //$gDir && $dir = $gDir; //strstr($dir,'.')!==false && self::alert('What are you doing?','',1000000); //strstr($dir,'..')!==false && self::alert('What are you doing?','',1000000); $sDir_PATH = self::path_join(iPATH, $dir); $iDir_PATH = self::path_join($sDir_PATH, $gDir); // print_r('$sDir_PATH='.$sDir_PATH."\n"); // print_r('$iDir_PATH='.$iDir_PATH."\n"); strpos($iDir_PATH, $sDir_PATH) === false && self::_error(array('code' => 0, 'state' => 'DIR_Error')); if (!is_dir($iDir_PATH)) { return false; } $url = iURL::make('dir'); if ($handle = opendir($iDir_PATH)) { while (false !== ($rs = readdir($handle))) { // print_r('$rs='.$rs."\n"); $filepath = self::path_join($iDir_PATH, $rs); $filepath = rtrim($filepath, '/'); // print_r('$filepath='.$filepath."\n"); $sFileType = @filetype($filepath); // print_r('$sFileType='.$sFileType."\n"); // var_dump($sDir_PATH,$filepath); $path = str_replace($sDir_PATH, '', $filepath); $path = ltrim($path, '/'); if ($sFileType == "dir" && !in_array($rs, array('.', '..', 'admincp'))) { $dirArray[] = array( 'path' => $path, 'name' => $rs, 'url' => $url . urlencode($path), ); } if ($sFileType == "file" && !in_array($rs, array('..', '.iPHP'))) { $filext = iFS::get_ext($rs); $fileinfo = array( 'path' => $path, 'dir' => dirname($path), 'url' => iFS::fp($path, '+http'), 'name' => $rs, 'modified' => get_date(filemtime($filepath), "Y-m-d H:i:s"), 'md5' => md5_file($filepath), 'ext' => $filext, 'size' => iFS::sizeUnit(filesize($filepath)), ); if ($type) { in_array(strtolower($filext), $type) && $fileArray[] = $fileinfo; } else { $fileArray[] = $fileinfo; } } } } $a['DirArray'] = (array) $dirArray; $a['FileArray'] = (array) $fileArray; $a['pwd'] = str_replace($sDir_PATH, '', $iDir_PATH); $a['pwd'] = trim($a['pwd'], '/'); $pos = strripos($a['pwd'], '/'); $a['parent'] = ltrim(substr($a['pwd'], 0, $pos), '/'); $a['URI'] = $url; // var_dump($a); // exit; return $a; } public static function info($path) { return (OBJECT) pathinfo($path); } public static function path($p = '') { $p = str_replace("\0", '', $p); $end = substr($p, -1); $a = explode('/', $p); $o = array(); $c = count($a); for ($i = 0; $i < $c; $i++) { if ($a[$i] == '.' || $a[$i] == '') { continue; } if ($a[$i] == '..' && $i > 0 && end($o) != '..') { array_pop($o); } else { $o[] = $a[$i]; } } $o[0] == 'http:' && $o[0] = 'http:/'; return ($p[0] == '/' ? '/' : '') . implode('/', $o) . ($end == '/' ? '/' : ''); } public static function path_is_absolute($path) { // this is definitive if true but fails if $path does not exist or contains a symbolic link if (@realpath($path) == $path) { return true; } if (strlen($path) == 0 || $path[0] == '.') { return false; } // windows allows absolute paths like this if (preg_match('#^[a-zA-Z]:\\\\#', $path)) { return true; } // a path starting with / or \ is absolute; anything else is relative return (bool) preg_match('#^[/\\\\]#', $path); } public static function path_join($base, $path, $rtrim = false) { //if (!self::path_is_absolute($path)) $path = rtrim($base, '/') . '/' . ltrim($path, '/'); $path = self::path($path); $rtrim && $path = rtrim($path, '/') . '/'; return $path; } //文件名 public static function name($fn) { $_fn = substr(strrchr($fn, "/"), 1); return array('name' => substr($_fn, 0, strrpos($_fn, ".")), 'path' => substr($fn, 0, strrpos($fn, ".")), ); } // 获得文件扩展名 public static function get_ext($fn) { return pathinfo($fn, PATHINFO_EXTENSION); //return substr(strrchr($fn, "."), 1); } // 获取文件大小 public static function sizeUnit($filesize) { $SU = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); $n = 0; while ($filesize >= 1024) { $filesize /= 1024; $n++; } return round($filesize, 2) . ' ' . $SU[$n]; } //-----------upload------------- public static function get_dir() { $dir = self::path_join(iPATH, self::$config['dir']); return rtrim($dir, '/') . '/'; } public static function mk_udir($_dir = '') { $FileDir = $_dir ? $_dir : get_date(0, self::$config['dir_format']); $FileDir = rtrim($FileDir, '/') . '/'; $FileDir = ltrim($FileDir, './'); $RootPath = self::get_dir() . $FileDir; $RootPath = rtrim($RootPath, '/') . '/'; self::mkdir($RootPath); return array($RootPath, $FileDir); } public static function save_ufile($tn, $fp) { if (function_exists('move_uploaded_file') && @move_uploaded_file($tn, $fp)) { @chmod($fp, 0644); } elseif (@copy($tn, $fp)) { @chmod($fp, 0644); } elseif (is_readable($tn)) { if ($fp = @fopen($tn, 'rb')) { @flock($fp, 2); $filedata = @fread($fp, @filesize($tn)); @fclose($fp); } if ($fp = @fopen($fp, 'wb')) { @flock($fp, 2); @fwrite($fp, $filedata); @fclose($fp); @chmod($fp, 0644); } else { return self::_error(array('code' => 0, 'state' => 'Error')); } } else { return self::_error(array('code' => 0, 'state' => 'UNKNOWN')); } } public static function _data($value) { $keys = array( 'code','fid','md5','size', 'oname','name','fname','dir','ext', 'RootPath','path','dirRootPath' ); return array_combine($keys ,$value); } public static function _array($code, $frs, $RP) { $value = array( $code,$frs->id,$frs->filename,$frs->size, $frs->ofilename,$frs->filename, $frs->filename . "." . $frs->ext, $frs->path,$frs->ext, $RP . '/' . $frs->path . $frs->filename . "." . $frs->ext, $frs->filepath, $RP . '/' . $frs->path, ); return self::_data($value); } public static function IO($FileName = '', $udir = '', $FileExt = 'jpg',$type='3',$filedata=null) { $filedata===null && $filedata = file_get_contents('php://input'); if (empty($filedata)) { return false; } list($RootPath, $FileDir) = self::mk_udir($udir); // 文件保存目录方式 $file_md5 = md5($filedata); $FileName OR $FileName = $file_md5; $FileSize = strlen($filedata); $FileExt = self::valid_ext($FileName . "." . $FileExt); //判断文件类型 if ($FileExt === false) { return false; } $FilePath = $FileDir . $FileName . "." . $FileExt; $FileRootPath = $RootPath . $FileName . "." . $FileExt; self::write($FileRootPath, $filedata); $fid = self::insert_filedata(array($FileName,'',$FileDir,'',$FileExt,$FileSize), $type); self::hook('upload',array($FileRootPath,$FileExt)); $value = array( 1,$fid,$file_md5,$FileSize, '',$FileName,$FileName.".".$FileExt, $FileDir,$FileExt, $FileRootPath,$FilePath,$RootPath ); return self::_data($value); } public static function base64ToFile($base64Data, $udir = '', $FileExt = 'png') { if (empty($base64Data)) {return false;} $filedata = base64_decode($base64Data); return self::IO(null, $udir,$FileExt,'2',$filedata); } public static function upload($field, $udir = '', $FileName = '', $ext = '') { if ($_FILES[$field]['name']) { $tmp_file = $_FILES[$field]['tmp_name']; if (!is_uploaded_file($tmp_file)) { return self::_error(array('code' => 0, 'state' => 'UNKNOWN')); } if ($_FILES[$field]['error'] > 0) { switch ((int) $_FILES[$field]['error']) { case UPLOAD_ERR_NO_FILE: @unlink($tmp_file); return self::_error(array('code' => 0, 'state' => 'NOFILE')); break; case UPLOAD_ERR_FORM_SIZE: @unlink($tmp_file); return self::_error(array('code' => 0, 'state' => 'UPLOAD_MAX')); break; } return self::_error(array('code' => 0, 'state' => 'UNKNOWN')); } $oFileName = $_FILES[$field]['name']; $FileExt = self::valid_ext($oFileName); //判断文件类型 if ($FileExt === false) { return false; } list($RootPath, $FileDir) = self::mk_udir($udir); // 文件保存目录方式 if (self::$data) { $fid = self::$data->id; $file_md5 = self::$data->filename; $oFileName = self::$data->ofilename; $FileDir = self::$data->path; $FileExt = self::$data->ext; $FileSize = self::$data->size; } else { $file_md5 = md5_file($tmp_file); $frs = self::get_filedata('filename', $file_md5); if ($frs) { return self::_array(1, $frs, $RootPath); } $ext && $FileExt = $ext; $FileSize = @filesize($tmp_file); } $FileName OR $FileName = $file_md5; $FilePath = $FileDir . $FileName . "." . $FileExt; $FileRootPath = self::fp($FilePath, "+iPATH"); $ret = self::save_ufile($tmp_file, $FileRootPath); @unlink($tmp_file); if ($fid) { self::update_filedata(array( 'ofilename' => $oFileName, 'ext' => $FileExt, 'size' => $FileSize, ), $fid); } else { $fid = self::insert_filedata(array($file_md5,$oFileName,$FileDir,'',$FileExt,$FileSize), 0); } self::hook('upload',array($FileRootPath,$FileExt)); $value =array( 1,$fid,$file_md5,$FileSize, $oFileName,$FileName,$FileName.".".$FileExt, $FileDir,$FileExt, $FileRootPath,$FilePath,$RootPath ); return self::_data($value); } else { return false; } } public static function check_image_bin($path,$bin=false){ if(empty($path)){ return false; } if($bin){ $head = substr($path, 0,16); }else{ if(!is_file($path)) return false; $fh = fopen($path, "rb"); //必须使用rb来读取文件,这样能保证跨平台二进制数据的读取安全 //仅读取前面的8个字节 $head = fread($fh, 16); fclose($fh); } $arr = unpack("C*", $head); $string = null; foreach ($arr as $k => $C) { if($C>=48 && $C<=127){ $string.=chr($C); } } if(empty($string)){ return false; } $string = strtoupper($string); $format = array( 'JFIF','TIFF','RIFF', 'PNG','GIF89A','GIF87A','JPEG', 'BMP','WEBP', 'JPEG 2000','EXIF','BPG','SVG' ); foreach ($format as $key => $f) { if(strpos($string, $f)!==false){ return $f; } } return false; } public static function allow_files($exts) { $exts_array = explode(',', $exts); foreach ($exts_array as $key => $ext) { if (!in_array($ext, self::$EXTS)) { return false; } } return true; } public static function check_ext($ext, $path = true) { $path && $ext = self::get_ext($ext); $ext = strtolower($ext); $allow = self::allow_files($ext); return $allow ? true : false; } public static function valid_ext($fn) { $_ext = strtolower(self::get_ext($fn)); $ext = self::check_ext($_ext, 0) ? $_ext : 'file'; if (self::$force_ext !== false) { (empty($_ext) || strlen($_ext) > 4 || $ext == 'file') && $ext = self::$force_ext; return $ext; } if (!self::$valid_ext) { return $ext; } $ext_array = explode(',', strtolower(self::$config['allow_ext'])); if (in_array($_ext, $ext_array)) { return $ext; } else { self::$ERROR = self::_error(array('code' => 0, 'state' => 'TYPE','file'=>$fn)); return false; } } public static function fp($f, $m = '+http', $_config = null) { $config = $_config ? $_config : self::$config; $url = self::$config['url']; switch ($m) { case '+http': $fp = rtrim($url, '/') . '/' . ltrim($f, '/'); break; case '-http': $fp = str_replace($url, '', $f); break; case 'http2iPATH': $f = str_replace($url, '', $f); $fp = self::path_join(iPATH, $config['dir'], '/') . ltrim($f, '/'); break; case 'iPATH2http': $f = str_replace(self::path_join(iPATH, $config['dir']), '', $f); $fp = $url . $f; break; case '+iPATH': $fp = self::path_join(iPATH, $config['dir'], '/') . ltrim($f, '/'); break; case '-iPATH': $fp = str_replace(self::path_join(iPATH, $config['dir']), '', $f); break; } return $fp; } public static function filename($path) { $path = trim($path); if(self::checkHttp($path)){ $url = self::url(); $uri = parse_url($url); if (stripos($path,$uri['host']) !== false){ $path = self::fp($path,'-http'); }else{ return false; } } $name = basename($path); $name = substr($name,0, 32); return $name; } //--------upload---end------------------------------- public static function http($http, $ret = '', $times = 0) { $frs = self::get_filedata('ofilename', $http); if ($frs) { if ($ret == 'array') { return self::_array(1, $frs, $RootPath); } return $frs->filepath; } $FileExt = self::valid_ext($http); //判断过滤文件类型 if ($FileExt === false) { return false; } $fdata = iHttp::remote($http); if ($fdata) { list($RootPath, $FileDir) = self::mk_udir($udir); // 文件保存目录方式 $file_md5 = md5($fdata); $frs = self::get_filedata('filename', $file_md5); if ($frs) { $FilePath = $frs->filepath; $FileRootPath = iFS::fp($FilePath, "+iPATH"); if (!is_file($FileRootPath)) { self::mkdir(dirname($FileRootPath)); self::write($FileRootPath, $fdata); self::hook('upload',array($FileRootPath,$FileExt)); // self::watermark($FileExt, $FileRootPath); // self::cloud_write($FileRootPath); } if ($ret == 'array') { return self::_array(1, $frs, $RootPath); } } else { $FileName = $file_md5 . "." . $FileExt; $FilePath = $FileDir . $FileName; $FileRootPath = $RootPath . $FileName; self::write($FileRootPath, $fdata); $FileSize = @filesize($FileRootPath); empty($FileSize) && $FileSize = 0; $fid = self::insert_filedata(array($file_md5,$http,$FileDir,$intro,$FileExt,$FileSize),1); self::hook('upload',array($FileRootPath,$FileExt)); if ($ret == 'array') { $value =array( 1,$fid,$file_md5,$FileSize, $http,$FileName,$FileName.".".$FileExt, $FileDir,$FileExt, $FileRootPath,$FilePath,$RootPath ); return self::_data($value); } } return $FilePath; } else { // if ($times < 3) { // $times++; // return self::http($http,$ret,$times); // } else { return false; // } } } public static function hook($h,$args) { $call = self::$CALLABLE[$h]; is_array($call) && $_call = reset($call); if(is_array($_call)){ foreach ($call as $key => $cb) { is_callable($cb) && call_user_func_array($cb, $args); } }else{ if ($call && is_callable($call)) { return call_user_func_array($call, $args); } } } //------callable----- public static function insert_filedata($value, $type = 0,$status=1) { $keys = array('filename','ofilename','path','intro','ext','size'); $data = array_combine($keys ,$value); return self::hook('insert',array($data, $type,$status)); } public static function update_filedata($data, $fid = 0) { if (empty($fid)) { return; } return self::hook('update',array($data, $fid)); } public static function get_filedata($f, $v,$s='*') { return self::hook('get',array($f,$v,$s)); } //------------- public static function _error($e, $break = false) { $stateMap = array( "UPLOAD_MAX" => "文件大小超出 upload_max_filesize 限制", "MAX_FILE_SIZE" => "文件大小超出 MAX_FILE_SIZE 限制", "文件未被完整上传", "没有文件被上传", "NOFILE" => "上传文件为空", "POST" => "文件大小超出 post_max_size 限制", "SIZE" => "文件大小超出网站限制", "TYPE" => "不允许的文件类型", "DIR" => "目录创建失败", "IO" => "输入输出错误", "UNKNOWN" => "未知错误", "Error" => "Upload Unknown Error (fopen)", "MOVE" => "文件保存时出错", "DIR_Error" => "您访问的目录有问题", ); $msg = $e['file'].$stateMap[$e['state']]; if (self::$ERROR_TYPE) { $e['state'] = $msg; if (self::$ERROR_TYPE === 'json') { return json_encode($e); } return $e; } else { exit('<script type="text/javascript">window.top.alert("' . $msg . '");</script>'); } } }